// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

/**
 * @brief
 *
 * @version  0.1
 * @author   yuanchenxi
 * @date     2024.12.20
 */
#include "Import/BDFImport/BulkData/Material/MAT9FParser.h"

#include <algorithm>
#include <cstdint>
#include <iostream>

#include "Utility/Logging/SGLogger.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Material/IMAT9FService.h"

#include "Import/BDFImport/BDFParserBase.h"

BULKDATA_ENTRY_PARSER_REG (MAT9F);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::DataStructure;

/*
// file://./../../Doc/MarkDown/BulkData/MAT9F/MAT9F.md>
*/
enum MAT9Fkey : std::uint8_t
{
    MAT9FKey_MID    = 2,   // 材料识别号
    MAT9FKey_G11    = 3,   // G11 元素
    MAT9FKey_G12    = 4,   // G12 元素
    MAT9FKey_G13    = 5,   // G13 元素
    MAT9FKey_G14    = 6,   // G14 元素
    MAT9FKey_G15    = 7,   // G15 元素
    MAT9FKey_G16    = 8,   // G16 元素
    MAT9FKey_G22    = 9,   // G22 元素
    MAT9FKey_G23    = 12,  // G23 元素
    MAT9FKey_G24    = 13,  // G24 元素
    MAT9FKey_G25    = 14,  // G25 元素
    MAT9FKey_G26    = 15,  // G26 元素
    MAT9FKey_G33    = 16,  // G33 元素
    MAT9FKey_G34    = 17,  // G34 元素
    MAT9FKey_G35    = 18,  // G35 元素
    MAT9FKey_G36    = 19,  // G36 元素
    MAT9FKey_G44    = 22,  // G44 元素
    MAT9FKey_G45    = 23,  // G45 元素
    MAT9FKey_G46    = 24,  // G46 元素
    MAT9FKey_G55    = 25,  // G55 元素
    MAT9FKey_G56    = 26,  // G56 元素
    MAT9FKey_G66    = 27,  // G66 元素
    MAT9FKey_GE     = 38,  // 结构阻尼系数
    MAT9FKey_GEIJ11 = 42,  // GEIJ11 阻尼矩阵元素
    MAT9FKey_GEIJ12 = 43,  // GEIJ12 阻尼矩阵元素
    MAT9FKey_GEIJ13 = 44,  // GEIJ13 阻尼矩阵元素
    MAT9FKey_GEIJ14 = 45,  // GEIJ14 阻尼矩阵元素
    MAT9FKey_GEIJ15 = 46,  // GEIJ15 阻尼矩阵元素
    MAT9FKey_GEIJ16 = 47,  // GEIJ16 阻尼矩阵元素
    MAT9FKey_GEIJ22 = 48,  // GEIJ22 阻尼矩阵元素
    MAT9FKey_GEIJ23 = 49,  // GEIJ23 阻尼矩阵元素
    MAT9FKey_GEIJ24 = 52,  // GEIJ24 阻尼矩阵元素
    MAT9FKey_GEIJ25 = 53,  // GEIJ25 阻尼矩阵元素
    MAT9FKey_GEIJ26 = 54,  // GEIJ26 阻尼矩阵元素
    MAT9FKey_GEIJ33 = 55,  // GEIJ33 阻尼矩阵元素
    MAT9FKey_GEIJ34 = 56,  // GEIJ34 阻尼矩阵元素
    MAT9FKey_GEIJ35 = 57,  // GEIJ35 阻尼矩阵元素
    MAT9FKey_GEIJ36 = 58,  // GEIJ36 阻尼矩阵元素
    MAT9FKey_GEIJ44 = 59,  // GEIJ44 阻尼矩阵元素
    MAT9FKey_GEIJ45 = 62,  // GEIJ45 阻尼矩阵元素
    MAT9FKey_GEIJ46 = 63,  // GEIJ46 阻尼矩阵元素
    MAT9FKey_GEIJ55 = 64,  // GEIJ55 阻尼矩阵元素
    MAT9FKey_GEIJ56 = 65,  // GEIJ56 阻尼矩阵元素
    MAT9FKey_GEIJ66 = 66,  // GEIJ66 阻尼矩阵元素
};

Common::Status BDF::BULKDATA::ParseMAT9F (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                          std::vector<std::string>&                               dividedEntryInfo)
{
    // 创建一个用于保存MAT9F材料数据的临时结构体对象
    FEM::MAT9FData tempData;

    // TODO(bug 001) 填写m_domainId的正确值
    // 目前m_domainId硬编码为1，需要进一步确认是否正确
    tempData.m_domainId = 1;

    int curIDKey = 1;  // 当前处理的条目索引

    // 遍历所有分割后的条目信息
    for (auto curStrKey : dividedEntryInfo)
    {
        // 检查当前条目是否为空
        bool const isEmpty = is_all_space (curStrKey);
        if (isEmpty)
        {
            curIDKey++;
            continue;
        }

        // 将字符串转换为科学计数法

        // 根据条目ID，将解析后的数值存入对应的MAT9F字段
        switch (curIDKey)
        {
        case MAT9FKey_MID:
            tempData.m_id = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G11:
            tempData.m_G[0] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G12:
            tempData.m_G[1] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G13:
            tempData.m_G[2] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G14:
            tempData.m_G[3] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G15:
            tempData.m_G[4] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G16:
            tempData.m_G[5] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G22:
            tempData.m_G[6] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G23:
            tempData.m_G[7] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G24:
            tempData.m_G[8] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G25:
            tempData.m_G[9] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G26:
            tempData.m_G[10] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G33:
            tempData.m_G[11] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G34:
            tempData.m_G[12] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G35:
            tempData.m_G[13] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G36:
            tempData.m_G[14] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G44:
            tempData.m_G[15] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G45:
            tempData.m_G[16] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G46:
            tempData.m_G[17] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G55:
            tempData.m_G[18] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G56:
            tempData.m_G[19] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_G66:
            tempData.m_G[20] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GE:
            tempData.m_GE = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ11:
            tempData.m_GEIJ[0] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ12:
            tempData.m_GEIJ[1] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ13:
            tempData.m_GEIJ[2] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ14:
            tempData.m_GEIJ[3] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ15:
            tempData.m_GEIJ[4] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ16:
            tempData.m_GEIJ[5] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ22:
            tempData.m_GEIJ[6] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ23:
            tempData.m_GEIJ[7] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ24:
            tempData.m_GEIJ[8] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ25:
            tempData.m_GEIJ[9] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ26:
            tempData.m_GEIJ[10] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ33:
            tempData.m_GEIJ[11] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ34:
            tempData.m_GEIJ[12] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ35:
            tempData.m_GEIJ[13] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ36:
            tempData.m_GEIJ[14] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ44:
            tempData.m_GEIJ[15] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ45:
            tempData.m_GEIJ[16] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ46:
            tempData.m_GEIJ[17] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ55:
            tempData.m_GEIJ[18] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ56:
            tempData.m_GEIJ[19] = convertToI64 (curStrKey);
            break;
        case MAT9FKey_GEIJ66:
            tempData.m_GEIJ[20] = convertToI64 (curStrKey);
            break;
        default:
            break;
        }
        curIDKey++;
    }

    return dbServiceFactory->get<IMAT9FService> ()->Add (tempData);
}
